package chro_final;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/** 
 * main class
 * 
 * @version 1.0
 * 
 * @author Roch Dionnet
*/
public final class Chro_final {

    /** 
     * main function.
     * 
     * @param args
     *            unused
    */
    public static void main(String[] args) {
        
        
        if(fillLogFile) {
        
            File logFile = new File("log.txt");
            logFile.delete();
        }
        chromosomes = new Chromosome[chromosomesPerGen];
        
        for(int i = 0; i < chromosomesPerGen; i++)
            chromosomes[i] = new Chromosome((int) (Math.random() * 100));
        
        Chromosome b1 = null, b2 = null;
        while((b1==null || b2==null) || (b1.getScore()!=goal && b2.getScore()!=goal && genCount < maxGenCount)) {
            
            sortChromosomes();
            
            if(fillLogFile)
                appendToLogFile(chromosomes);
            
            b1 = chromosomes[chromosomes.length-1];
            b2 = chromosomes[chromosomes.length-2];
            
            chromosomes = Chromosome.newGen(b1, b2, chromosomesPerGen, mutationFrequency);
            genCount++;
        }
        
        genCount--;
        
        System.out.println("b1 : " + b1.toString() + "; score : " + b1.getScore());
        System.out.println("b2 : " + b2.toString() + "; score : " + b2.getScore());
        System.out.println((genCount != maxGenCount ? "Gene count : " : "Program terminated, gen limit attained : ") + genCount);
    }
    
    /** 
     * Sorts <i>chromosomes</i> by score in ascending order.
    */
    private static void sortChromosomes() {
        
        for(int i=1;i<=chromosomes.length-1;i++) {
            
            int j = i;
            while (j > 0 && Math.abs(goal-chromosomes[j-1].getScore()) < Math.abs(goal-chromosomes[j].getScore())) {
            
                Chromosome swap = chromosomes[j];
                chromosomes[j] = chromosomes[j-1];
                chromosomes[j-1]= swap;
                j--;
            }
        }
    }   
    
    /**
     * Appends a chromosome generation at the end of the log file.
     * 
     * @param gen The generation to append.
     */
    private static void appendToLogFile(Chromosome[] gen) {
        
        try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("log.txt", true)))) {
            
            out.println("========== gen " + genCount + " (max : " + maxGenCount + ") ==========");
            out.println();
            for(int i = 0; i<gen.length;i+=2) {
               
                out.println("c"+i+" : " + gen[i].toString() + " = " + gen[i].getScore() + "; "
                        + "c"+(i+1)+" : " + gen[i+1].toString() + " = " + gen[i+1].getScore());
            }
            out.println();
            out.close();
        }
        catch(IOException e) {
            //TODO
        }
    }
    
    /** 
     * Number of chromosomes per generation. Really, <i>chromosomes</i>' size.
     */
    private static final int chromosomesPerGen = 10;
    
    /**
     * The value chromosomes' scores have to get to.
     */
    private static final float goal = 18f;
    
    /**
     * Represents the current generation of chromosomes. 
     */
    private static Chromosome[] chromosomes;
    
    /**
     * Max number of generations.
     */
    private static final int maxGenCount = 100000;
    
    /**
     * Current generation number.
     */
    private static int genCount = 1;
    
    /**
     * Mutation frequency. Between 0 (no mutation) and 1 (all chromosomes mutate fully).
     */
    private static final float mutationFrequency = 0.1f;
    
    /**
     * Creates and fills a log file if set to <i>true</i>. The file will contain all the generations of chromosomes. 
     */
    private static final boolean fillLogFile = true;
}
